package com.jly.edu.controller;


import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jly.edu.common.dto.SysRoleDto;
import com.jly.edu.common.lang.Const;
import com.jly.edu.common.lang.Result;
import com.jly.edu.common.param.SysMenuParam;
import com.jly.edu.common.validated.UpdateGroup;
import com.jly.edu.entity.SysMenu;
import com.jly.edu.entity.SysRole;
import com.jly.edu.entity.SysRoleMenu;
import com.jly.edu.entity.SysUserRole;
import com.jly.edu.service.SysCommonService;
import com.jly.edu.service.SysRoleMenuService;
import com.jly.edu.service.SysRoleService;
import com.jly.edu.service.SysUserRoleService;
import com.jly.edu.utils.ConverUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author 作者：纪联友
 * @since 2021-10-22
 */
@RestController
@RequestMapping("/sys-role")
public class SysRoleController extends BaseController {

    @Autowired
    private SysRoleService sysRoleService;
    @Autowired
    private SysUserRoleService sysUserRoleService;
    @Autowired
    private SysRoleMenuService sysRoleMenuService;
    @Autowired
    private SysCommonService sysCommonService;

    /**
     * 获取role 分页
     * @param name
     * @return
     */
    @PreAuthorize("hasAnyAuthority('sys:role:list')")
    @GetMapping("/list")
    public Result getRoleList(String name){

        Page<SysRole> rolePages= sysRoleService.page(getPage(), new QueryWrapper<SysRole>().like(StrUtil.isNotBlank(name), "name", name));

        return Result.success(rolePages);
    }
    @PreAuthorize("hasAnyAuthority('sys:role:list')")
    @GetMapping("/allRoles")
    public Result getAllRoleList(){

        List<SysRole> sysRoles = sysRoleService.list(new QueryWrapper<SysRole>().eq("status", Const.STATUS_OFF));

        return Result.success(sysRoles);
    }
    @GetMapping("/info/{id}")
    @PreAuthorize("hasAuthority('sys:role:list')")
    public Result info(@PathVariable Long id) {
        SysRole role = sysRoleService.getById(id);
        SysRoleDto sysRoleDto = ConverUtil.convert(role, SysRoleDto.class);
        List<SysRoleMenu> roleMenus = sysRoleMenuService.list(new QueryWrapper<SysRoleMenu>().eq("role_id", id));
        List<Long> menuIds = roleMenus.stream().map(p -> p.getMenuId()).collect(Collectors.toList());
        sysRoleDto.setMenuIds(menuIds);
        return Result.success(sysRoleDto);
    }

    @PostMapping("/save")
    @PreAuthorize("hasAnyAuthority('sys:role:save')")
    public Result saveRole(@Validated @RequestBody SysRoleDto sysRoleDto){
        SysRole existCode = sysRoleService.getBaseMapper().selectOne(new QueryWrapper<SysRole>().eq("code", sysRoleDto.getCode()));
        if(existCode != null){
            return Result.fail("编码已经存在,请修改");
        }

        SysRole sysRole = new SysRole();
        sysRole.setCreateTime(LocalDateTime.now());
        sysRole.setStatus(Const.STATUS_ON);
        ConverUtil.convert(sysRoleDto,sysRole);
        sysRoleService.save(sysRole);
        return Result.success(sysRoleDto);
    }
    /**
     * 修改角色信息
     * @param sysRoleDto
     * @return
     */
    @PreAuthorize("hasAnyAuthority('sys:role:update')")
    @PostMapping("/update")
    public Result updateRole(@Validated(UpdateGroup.class) @RequestBody SysRoleDto sysRoleDto){
        sysRoleDto.setUpdateTime(LocalDateTime.now());
        sysRoleService.updateById(ConverUtil.convert(sysRoleDto, SysRole.class));
        //删除所有与当前菜单相关的权限缓存
        sysCommonService.clearUserAuthorityInfoByRoleId(sysRoleDto.getId());
        return Result.success(sysRoleDto);
    }

    @Transactional
    @PostMapping("/delete")
    @PreAuthorize("hasAuthority('sys:role:delete')")
    public Result delete(@RequestBody Long[] ids){
        if(ids == null || ids.length <= 0 ){
            return Result.fail("ids不能为空");
        }
        sysRoleService.removeByIds(Arrays.asList(ids));
        // 同步删除
        sysRoleMenuService.remove(new QueryWrapper<SysRoleMenu>().in("role_id", ids));
        sysUserRoleService.remove(new QueryWrapper<SysUserRole>().in("role_id", ids));

        // 缓存同步删除
        Arrays.stream(ids).forEach(id -> {
            // 更新缓存
            sysCommonService.clearUserAuthorityInfoByRoleId(id);
        });

        return Result.success("");
    }


    @Transactional
    @PostMapping("/perm/{roleId}")
    @PreAuthorize("hasAuthority('sys:role:perm')")
    public Result perm(@PathVariable("roleId") Long roleId, @RequestBody Long[] menuIds) {

        List<SysRoleMenu> sysRoleMenus = new ArrayList<>();

        Arrays.stream(menuIds).forEach(menuId -> {
            SysRoleMenu roleMenu = new SysRoleMenu();
            roleMenu.setMenuId(menuId);
            roleMenu.setRoleId(roleId);

            sysRoleMenus.add(roleMenu);
        });

        // 先删除原来的记录，再保存新的
        sysRoleMenuService.remove(new QueryWrapper<SysRoleMenu>().eq("role_id", roleId));
        sysRoleMenuService.saveBatch(sysRoleMenus);

        // 删除缓存
        sysCommonService.clearUserAuthorityInfoByRoleId(roleId);

        return Result.success(menuIds);
    }
}
